﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Tecnosop.Dominio;
using Tecnosop.WebUI.Models;
using Tecnosop.WebUI.Infrastructure.Notification;
using System.Web.UI;
using Rotativa;

namespace Tecnosop.WebUI.Controllers
{
    public partial class GuiaDespachoController : Controller
    {
        private Entidades db = new Entidades();

        #region CRUD

        [Authorize]
        public virtual ActionResult Index()
        {
            return View(db.GUIA_DE_DESPACHO.ToList());
        }

        public virtual ActionResult printPdfVentaDirecta(int idF, string RazonSocialF)
        {
            return new ActionAsPdf("VistaBlancaGd", new { idGD = idF, razonSocial = RazonSocialF }) { FileName = "GuiaDespacho.pdf" };
        }

        public virtual ActionResult VistaBlancaGd(int idGD, string razonSocial)
        {
            GUIA_DE_DESPACHO guia = db.GUIA_DE_DESPACHO.Find(idGD, razonSocial);
            Func<ITEM, string> GetTipo = Item =>
            {
                return Item != null ?
                    Item.EQUIPO != null ?
                        Item.EQUIPO.TIPO_EQUIPO :
                        Item.INSUMO != null ?
                            Item.INSUMO.TIPO_INSUMO : ""
                    : "";
            };
            List<DetalleGuiaDespachoViewModel> detalleGD = new List<DetalleGuiaDespachoViewModel>();
            foreach (var detalle in guia.DETALLE_GUIA_DE_DESPACHO)
            {
                ITEM item = db.ITEM.Find(detalle.CODIGO_ITEM);

                DetalleGuiaDespachoViewModel Det = new DetalleGuiaDespachoViewModel
                {
                    NUMERO_LINEA_DETALLE = detalle.LINEA_GUIA_DE_DESPACHO,
                    CODIGO_ITEM = detalle.CODIGO_ITEM,
                    //NUMERO_FACTURA = detalle.NUMERO_FACTURA,
                    //RAZON_SOCIAL = detalle.RAZON_SOCIAL,
                    CANTIDAD = detalle.CANTIDAD ?? 1,
                    //SUBTOTAL = detalle.SUBTOTAL ?? 0,
                    //PRECIO = GetPrecio(item)
                    valorUnitario = item.PRECIO ?? 0
                };

                Det.setDescripcion(GetTipo(item), item.MARCA, item.MODELO);

                detalleGD.Add(Det);
            }
            CLIENTE c = null;

            if (guia.FACTURA.FACTURA_CONVENIO != null)
            {
                c = guia.FACTURA.FACTURA_CONVENIO.CONVENIO.CLIENTE;

            }
            else if (guia.FACTURA.FACTURA_VENTA_DIRECTA != null)
            {
                c = guia.FACTURA.FACTURA_VENTA_DIRECTA.CLIENTE;

            }

            else if (guia.CONVENIO != null)
            {
                c = guia.CONVENIO.CLIENTE;
            }

            return View(new createGuiaDespachoStep1
            {
                NUMERO_FACTURA = guia.NUMERO_FACTURA,
                ID_GUIA_DE_DESPACHO_ = guia.ID_GUIA_DE_DESPACHO,
                RAZON_SOCIALGuia = razonSocial,
                DIRECCION_DE_DESPACHO = guia.DIRECCION_DE_DESPACHO,
                COMUNA = guia.COMUNA,
                REGION = guia.REGION,
                FECHA_INSTALACION = guia.FECHA_INSTALACION,
                DETALLE_GUIA_DESPACHOvm = detalleGD,
                COMENTARIO = guia.COMENTARIO,
                Cliente = c
            });
        }

        [Authorize]
        public virtual ActionResult Create()
        {
            ViewBag.REGIONES = new SelectList(db.REGION, "REGION1", "REGION1");
            ViewBag.EsConFacturaAsociada = false;

            return View();
        }

        public virtual ActionResult CreateConFacturaAsociada(int NUMERO_FACTURA, string RAZON_SOCIAL)
        {
            ViewBag.REGIONES = new SelectList(db.REGION, "REGION1", "REGION1");
            ViewBag.EsConFacturaAsociada = true;

            return View(Views.Create, new createGuiaDespachoStep1
                {
                    NUMERO_FACTURA = NUMERO_FACTURA,
                    RAZON_SOCIAL = RAZON_SOCIAL,
                });
        }

        public virtual ActionResult CreateConConcenioAsociada(int NUMERO_CONVENIO)
        {
            ViewBag.REGIONES = new SelectList(db.REGION, "REGION1", "REGION1");

            return View(Views.Create, new createGuiaDespachoStep1
            {
               NUMERO_CONVENIO=NUMERO_CONVENIO,
               COMENTARIO="Guía asociada a convenio, no representa venta"
            });
        }

        [HttpPost]
        [Authorize]
        public virtual ActionResult Create(createGuiaDespachoStep1 vmGD)
        {
            try
            {
                GUIA_DE_DESPACHO gd = new GUIA_DE_DESPACHO
                {
                    ID_GUIA_DE_DESPACHO=vmGD.ID_GUIA_DE_DESPACHO_,
                    REGION = vmGD.REGION,
                    NUMERO_FACTURA=vmGD.NUMERO_FACTURA,
                    NUMERO_CONVENIO=vmGD.NUMERO_CONVENIO,
                    RAZON_SOCIAL = vmGD.EsRazonSocialTecnosop != null
                        ? vmGD.EsRazonSocialTecnosop.Value ? "Comercializadora Tecnosop" : "Juan Carlos Maldonado Huerta"
                        : null,
                    RAZONSOCIALGUIA = vmGD.EsRazonSocialTecnosopGuia.Value ? "Comercializadora Tecnosop" : "Juan Carlos Maldonado Huerta",
                    COMENTARIO = vmGD.COMENTARIO,
                    FECHA_INSTALACION = DateTime.Today,
                    CIUDAD = vmGD.CIUDAD,
                    COMUNA=vmGD.COMUNA,
                    DIRECCION_DE_DESPACHO=vmGD.DIRECCION_DE_DESPACHO,
                    VISIBLE=true                 

                };

                db.GUIA_DE_DESPACHO.Add(gd);
                db.SaveChanges();

                if (vmGD.NUMERO_FACTURA.HasValue && !String.IsNullOrEmpty(vmGD.RAZON_SOCIAL))
                {
                    FACTURA factura = db.FACTURA.Find(vmGD.NUMERO_FACTURA.Value, vmGD.RAZON_SOCIAL);
                    factura.GUIA_DE_DESPACHO.Add(gd);
                    db.Entry(factura).State = System.Data.EntityState.Modified;
                    db.SaveChanges();
                }

                

                return RedirectToAction(Actions.Details(gd.ID_GUIA_DE_DESPACHO, gd.RAZONSOCIALGUIA));
            }
            catch
            {
                return View(vmGD);
            }
        }
        
        [Authorize]
        public virtual ActionResult Details(int idGD, string razonSocial)
        {
            GUIA_DE_DESPACHO guia = db.GUIA_DE_DESPACHO.Find(idGD,razonSocial);
            Func<ITEM, string> GetTipo = Item =>
            {
                return Item != null ?
                    Item.EQUIPO != null ?
                        Item.EQUIPO.TIPO_EQUIPO :
                        Item.INSUMO != null ?
                            Item.INSUMO.TIPO_INSUMO : ""
                    : "";
            };
            List<DetalleGuiaDespachoViewModel> detalleGD=new  List<DetalleGuiaDespachoViewModel>();
            foreach (var detalle in guia.DETALLE_GUIA_DE_DESPACHO)
            {
                ITEM item = db.ITEM.Find(detalle.CODIGO_ITEM);

                DetalleGuiaDespachoViewModel Det = new DetalleGuiaDespachoViewModel
                {
                    NUMERO_LINEA_DETALLE = detalle.LINEA_GUIA_DE_DESPACHO,
                    CODIGO_ITEM = detalle.CODIGO_ITEM,
                    //NUMERO_FACTURA = detalle.NUMERO_FACTURA,
                    //RAZON_SOCIAL = detalle.RAZON_SOCIAL,
                    CANTIDAD = detalle.CANTIDAD ?? 1,
                    //SUBTOTAL = detalle.SUBTOTAL ?? 0,
                    //PRECIO = GetPrecio(item)
                    valorUnitario= item.PRECIO ?? 0
                };

                Det.setDescripcion(GetTipo(item), item.MARCA, item.MODELO);

                detalleGD.Add(Det);
            }

         
            CLIENTE c=null;

            if (guia.FACTURA.FACTURA_CONVENIO != null)
            {
                c = guia.FACTURA.FACTURA_CONVENIO.CONVENIO.CLIENTE;
                
            }
            else if (guia.FACTURA.FACTURA_VENTA_DIRECTA != null)
            {
                c = guia.FACTURA.FACTURA_VENTA_DIRECTA.CLIENTE;
              
            }

            return View(new createGuiaDespachoStep1
            {
                NUMERO_FACTURA = guia.NUMERO_FACTURA,
                ID_GUIA_DE_DESPACHO_ = guia.ID_GUIA_DE_DESPACHO,
                RAZON_SOCIALGuia= razonSocial,
                DIRECCION_DE_DESPACHO=guia.DIRECCION_DE_DESPACHO,
                COMUNA = guia.COMUNA,
                REGION=guia.REGION,
                FECHA_INSTALACION=guia.FECHA_INSTALACION,            
                DETALLE_GUIA_DESPACHOvm = detalleGD,
                COMENTARIO=guia.COMENTARIO,
                Cliente = c
            });
        }

        [Authorize]
        public virtual ActionResult Delete(int id)
        {
            return View();
        }

        [HttpPost]
        [Authorize]
        public virtual ActionResult Delete(int id, FormCollection collection)
        {
            try
            {
                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }

        #endregion

        #region "Grid Detalle"

        [HttpPost]
        [Authorize]
        public virtual ActionResult GridEditDetalleGuia(int NUMERO_GUIA, int? idFactura, string razonSocial)
        {
            DetalleGuiaDespachoViewModel detalleVM = new DetalleGuiaDespachoViewModel();

            if (TryUpdateModel(detalleVM))
            {
                try
                {
                    GUIA_DE_DESPACHO guia = db.GUIA_DE_DESPACHO.Find(NUMERO_GUIA, razonSocial);
                    var detalle = guia.DETALLE_GUIA_DE_DESPACHO.Single(d => d.LINEA_GUIA_DE_DESPACHO == detalleVM.NUMERO_LINEA_DETALLE);

                    ///int precio_item_detalle = db.ITEM.Find(detalleVM.CODIGO_ITEM).PRECIO ?? 0;
                    int cantidad_inicial = detalle.CANTIDAD ?? 0;
                    int codigo_item_inicial = detalle.CODIGO_ITEM;

                    detalle.CODIGO_ITEM = detalleVM.CODIGO_ITEM;
                    detalle.CANTIDAD = detalleVM.CANTIDAD;
                    //detalle.SUBTOTAL = detalleVM.CANTIDAD * precio_item_detalle;

                    db.Entry(detalle).State = System.Data.EntityState.Modified;
                    db.SaveChanges();

                    // factura.FACTURA.TOTAL -= cantidad_inicial * db.ITEM.Find(codigo_item_inicial).PRECIO;
                    //factura.FACTURA.TOTAL += detalleVM.CANTIDAD * precio_item_detalle;

                    db.Entry(guia).State = System.Data.EntityState.Modified;
                    db.SaveChanges();

                    this.ShowMessage(MessageType.Success, "Se guardaron los cambios correctamente");
                }
                catch
                {
                    this.ShowMessage(MessageType.Error, "Ocurrió un problema al tratar de editar la línea de detalle");
                }
            }

            return RedirectToAction(Actions.Details(NUMERO_GUIA, razonSocial));
        }
        
        [HttpPost]
        [Authorize]
        public virtual ActionResult GridAddDetalleGuia(int NUMERO_GUIA, int? idFactura, string razonSocial)
        {
            DetalleGuiaDespachoViewModel detalleVM = new DetalleGuiaDespachoViewModel();

            if (TryUpdateModel(detalleVM))
            {
                try
                {
                    //ITEM item = db.ITEM.Find(detalleVM.CODIGO_ITEM);
                    GUIA_DE_DESPACHO guia = db.GUIA_DE_DESPACHO.Find(NUMERO_GUIA,razonSocial);
                    DETALLE_GUIA_DE_DESPACHO detalle = new DETALLE_GUIA_DE_DESPACHO
                    {
                        CODIGO_ITEM = detalleVM.CODIGO_ITEM,
                       LINEA_GUIA_DE_DESPACHO =0,
                      //  RAZON_SOCIAL = detalleVM.RAZON_SOCIAL,
                        CANTIDAD = detalleVM.CANTIDAD
                        //SUBTOTAL = detalleVM.CANTIDAD * db.ITEM.Find(detalleVM.CODIGO_ITEM).PRECIO//detalleVM.SUBTOTAL
                    };

                    guia.DETALLE_GUIA_DE_DESPACHO.Add(detalle);
                    db.SaveChanges();

                    //factura.FACTURA.TOTAL += detalle.SUBTOTAL;
                    db.Entry(guia).State = System.Data.EntityState.Modified;
                    db.SaveChanges();

                    this.ShowMessage(MessageType.Success, "Se agregó correctamente la línea de detalle");
                }
                catch
                {
                    this.ShowMessage(MessageType.Error, "Ocurrió un problema al tratar de agregar la línea de detalle");
                }
            }
            return RedirectToAction(Actions.Details(NUMERO_GUIA, razonSocial));
        }

        [HttpPost]
        [Authorize]
        public virtual ActionResult GridDeleteDetalleGuia(int NUMERO_GUIA, int? idFactura, string razonSocial)
        {
            DetalleGuiaDespachoViewModel detalleVM = new DetalleGuiaDespachoViewModel();

            if (TryUpdateModel(detalleVM))
            {
                try
                {
                  GUIA_DE_DESPACHO guia = db.GUIA_DE_DESPACHO.Find(NUMERO_GUIA,razonSocial);
                    var detalle = guia.DETALLE_GUIA_DE_DESPACHO.Single(d => d.LINEA_GUIA_DE_DESPACHO == detalleVM.NUMERO_LINEA_DETALLE);

                    
                   
                   guia.DETALLE_GUIA_DE_DESPACHO.Remove(detalle);
                    db.SaveChanges();

                    //factura.FACTURA.TOTAL -= detalleVM.SUBTOTAL;
                    db.Entry(guia).State = System.Data.EntityState.Modified;
                    db.SaveChanges();

                    this.ShowMessage(MessageType.Success, "Se eliminó correctamente la línea de detalle");
                }
                catch
                {
                    this.ShowMessage(MessageType.Error, "Ocurrió un problema al tratar de eliminar la línea de detalle");
                }
            }

            return RedirectToAction(Actions.Details( NUMERO_GUIA, razonSocial));
        }

        #endregion

        #region Validaciones
        [OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
        [Authorize]
        public virtual JsonResult ValidaNumeroFacturaExiste(int? NUMERO_FACTURA, bool? EsRazonSocialTecnosop)
        {
            string razon = EsRazonSocialTecnosop.Value ? "Comercializadora Tecnosop" : "Juan Carlos Maldonado Huerta";
            if (EsRazonSocialTecnosop.HasValue)
            {
               
                return db.FACTURA.Any(f => f.NUMERO_FACTURA == NUMERO_FACTURA && f.RAZON_SOCIAL.Equals(razon))
                    ? Json(true, JsonRequestBehavior.AllowGet)
                    : Json("El número de factura ingresado no existe", JsonRequestBehavior.AllowGet);
            }
            else if (EsRazonSocialTecnosop.HasValue == false && string.IsNullOrEmpty(razon) == true)
            {
               return Json(true, JsonRequestBehavior.AllowGet);
            }
            else 
            {
                return Json("Ingrese una razón social factura.", JsonRequestBehavior.AllowGet);
            }
        }

        [OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
        [Authorize]
        public virtual JsonResult ValidaNumeroGuiaUnico(int ID_GUIA_DE_DESPACHO_, bool? EsRazonSocialTecnosopGuia)
        {
            if (EsRazonSocialTecnosopGuia.HasValue)
            {
                string razon = EsRazonSocialTecnosopGuia.Value ? "Comercializadora Tecnosop" : "Juan Carlos Maldonado Huerta";
                if (EsRazonSocialTecnosopGuia == true)
                {
                    razon = "Comercializadora Tecnosop";
                }
                else if (EsRazonSocialTecnosopGuia == false)
                {
                    razon = "Juan Carlos Maldonado Huerta";
                }
               
                return !db.GUIA_DE_DESPACHO.Any(f => f.ID_GUIA_DE_DESPACHO == ID_GUIA_DE_DESPACHO_ && f.RAZONSOCIALGUIA.Equals(razon))
                    ? Json(true, JsonRequestBehavior.AllowGet)
                    : Json("El número de guía ingresado ya fue ocupado para otra guía.", JsonRequestBehavior.AllowGet);
            }
            else
            {
                return Json("Ingrese una razón social.", JsonRequestBehavior.AllowGet);
            }
        }

         #endregion

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}
